package upm.pb4agent.team2;

import jade.content.AgentAction;
import jade.content.Concept;
import jade.content.ContentElement;
import jade.content.lang.Codec.CodecException;
import jade.content.onto.OntologyException;
import jade.content.onto.UngroundedException;
import jade.content.onto.basic.Action;
import jade.core.AID;
import jade.core.Agent;
import jade.core.behaviours.SimpleBehaviour;
import jade.lang.acl.ACLMessage;
import jade.lang.acl.MessageTemplate;
import upm.pb4agent.ontology.RaceFinished;
import upm.pb4agent.ontology.SubscribeReferee;
import upm.pb4agent.team2.internalOntology.DestroyTeamPlease;


/**
 * Team 2 launcher agent class
 * 
 * @author Alejandro Bustamante
 * @version 1.0
 */

public class AgTeam2 extends Team2BaseAgent 
{
	private static final long serialVersionUID = -4403193255926423833L;
	
	private int killCounter = 0;

	protected void setup() 
	{
		super.setup();
		
		registerOnDF(Constants.AGTEAM2);
		
		addBehaviour(new MessageListener(this));
		addBehaviour(new SubscribeToReferee(this));

		try 
		{
			Thread.sleep(500);
		} 
		catch (InterruptedException e) 
		{
			e.printStackTrace();
		}

		createAndStartAgent(Constants.TEAM2MANAGERNAME, "upm.pb4agent.team2.Manager", new String[] {  });
		
	}
	
	class MessageListener extends SimpleBehaviour 
	{
		private static final long serialVersionUID = -8825681408560057420L;

		public MessageListener(Agent agent) 
		{
			super(agent);
		}

		@Override
		public void action() 
		{
			ACLMessage aclMessage = receive(MessageTemplate.and(MessageTemplate.MatchLanguage(codec.getName()), MessageTemplate.or(MessageTemplate.MatchOntology(ontology.getName()), MessageTemplate.MatchOntology(internalOntology.getName()))));

			if (aclMessage != null) 
			{
				if (aclMessage.getPerformative() == ACLMessage.INFORM) 
				{
					try
					{
						ContentElement contentElement = null;
						contentElement = getContentManager().extractContent(aclMessage);
						
						if (contentElement instanceof AgentAction)
						{
							Action action = (Action) contentElement;
							Concept concept = action.getAction();
							
							if (concept instanceof DestroyTeamPlease)
							{
								killCounter ++;

								if (killCounter == 4) // this message is sent by the 4 rowers - it means each is ready to die
								{	
									printOut("<<< Killing Team 2 Manager and Rowers now >>>");
									destroyAgentsByName(Constants.ROWER21NAME, Constants.ROWER22NAME, Constants.ROWER23NAME, Constants.ROWER24NAME, Constants.TEAM2MANAGERNAME);
								}
							}

							if (concept instanceof RaceFinished)
							{
								if(((RaceFinished)concept).getBoatAID().getLocalName().endsWith("2"))
								{
									printOut(" <<< !!!! FINISHED RACE IN POSITION # "+((RaceFinished)concept).getPosition() +" !!!! >>>");
								}
							}
						}
					} 
					catch (UngroundedException e) 
					{
						e.printStackTrace();
					} 
					catch (CodecException e) 
					{
						e.printStackTrace();
					}
					catch (OntologyException e) 
					{
						e.printStackTrace();
					}
				}
			} 
			else 
			{
				// No message yet
				block();
			}
		}

		@Override
		public boolean done() 
		{
			return false;
		}

	}
	
	class SubscribeToReferee extends SimpleBehaviour 
	{
		private static final long serialVersionUID = 3494297806661568433L;
		private Boolean subscriptionSent = false;

		public SubscribeToReferee(Agent agent) 
		{
			super(agent);
		}

		@Override
		public void action() 
		{
			AID receiverAID = findAgentOnDF(myAgent, Constants.REFEREE);
			
			if (receiverAID != null)
			{
				sendSubscription(receiverAID);
			}
		}
		
		private void sendSubscription(AID receiverAID)
		{
			SubscribeReferee subscribeReferee = new SubscribeReferee();
			Action action = new Action(receiverAID, subscribeReferee);
			
			sendMessage(receiverAID, ACLMessage.SUBSCRIBE, action, SubscribeReferee.class.getSimpleName().toString());
			
			subscriptionSent = true;
		}

		@Override
		public boolean done() 
		{
			return subscriptionSent;
		}
	}

}